iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Mobile Development

單人開發者之路:React Native 與 Expo 帶你從開發到上架系列 第 16

Day 16 - React Native FlatList、RefreshControl 實作滑動式清單

  • 分享至 

  • xImage
  •  

本篇要來介紹React Native兩項核心Component

  • FlatList
  • RefreshControl

日常在FaceBook、Instgram、FoodPanda都會看到動態、菜單、限時動態
這些應用皆是使用FlatList清單元件產出
RefreshControl則是搭配FlatList
手指按住螢幕下拉時
能刷新清單內容、更新動態消息

FlatList

介紹

React Native滑動清單列核心Component
能讓資料以清單(List)的方式呈現
且對於大量資料有著高效能的處理表現
類似Html中的Table

以 Skype APP 群組名單為例
每位參與者,是FlatList裡的每一項元件
最後讀取群組裡的每個人,渲染到畫面上
https://ithelp.ithome.com.tw/upload/images/20230920/20130821ElIDqBUbBG.jpg

平常也適用於社交媒體消息、商品列表或聯絡人名單

使用方法

附上基本款程式碼

import React from 'react';
import { FlatList, View, Text } from 'react-native';

const data = [
  { key: '1', name: '列表項目 1' },
  { key: '2', name: '列表項目 2' },
  { key: '3', name: '列表項目 3' },
  // 增加更多列表項目...
];

const MyFlatList = () => {
  return (
    <View>
      <FlatList
        data={data}
        renderItem={({ item }) => <Text>{item.name}</Text>}
      />
    </View>
  );
};

export default MyFlatList;

輸出結果

https://ithelp.ithome.com.tw/upload/images/20230920/20130821MhsaWTxkP1.png

程式講解

  1. data為必填標籤
    使用陣列讓FlatList渲染內容至畫面上
    資料內容必須要有Key值,才能發揮長列表大量資料載入的效能
    另外Key值若有重複
    React Native會跳出重複警告

    Warning: Encountered two children with the same key, 3. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version

    此時需檢查data陣列內容的正確性

  2. renderItem為必填標籤
    每個項目的呈現方法皆在此設定

其他常用屬性講解

  1. keyExtractor 唯一值名稱指定
    假設陣列中物件沒有key,而是id
    這時就需要指定id為「唯一值」
    keyExtractor={(item) => item.id}
  2. contentContainerStyle 滑動清單列樣式
    設定FlatList的邊界、間距
    但不調整內容(Item)裡的樣式
    contentContainerStyle={{ paddingBottom: 50 }}
  3. ListEmptyComponent 無內容顯示方法
    當陣列無任何資料,可以使用自訂元件向使用者顯示
    ListEmptyComponent={
        <Text className="text-xl text-center font-bold mt-3">
             查無資料
        </Text>
    }
    

加上Style排版後實作Skype聯絡人特效展示:
https://snack.expo.dev/@peter_lu/flatlistexample

踩坑紀錄

請看以下程式碼
使用ScrollView包覆FlatList

    <ScrollView>
      <FlatList
        data={data}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => (
          <View>
            <Text>{item.text}</Text>
          </View>
        )}
      />
    </ScrollView>

在模擬器運行時會跳出 Scroll Error

VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing and other functionality - use another VirtualizedList-backed container instead.

https://ithelp.ithome.com.tw/upload/images/20230920/20130821KaJW4nV8s0.png

解法:
React Native規定你已經有滑動選單
裡面就不能在放相同方向的滑動選單
會造成使用者體驗不佳

即使APP還是能執行
但每次跳出這項Error總是怪怪的

  1. 移除不必要的ScrollView,改回View
  2. 不移除,設定FlatList horizontal={true}
    保證外層垂直,內層水平滑動
  3. 兩種方向一樣的Scroll Component分開放

這也是為什麼
大家在滑FB、IG時
限時動態是水平滑動,一般動態是垂直滑動的原因了😯

RefreshControl

介紹

React Native刷新核心Component
官方規定只能在ScrollView或ListView上使用
有Scoll相關元件才能觸發刷新的意思
(FlatList是繼承ScrollView,因此也能使用此元件)

打開FaceBook動態,手指下拉看到轉圈圈的特效出現
則是啟動RefreshControlrefreshing事件
https://ithelp.ithome.com.tw/upload/images/20230920/20130821rzSxYH0HoY.jpg

使用方法

import React, { useState } from "react";
import { ScrollView, View, Text, FlatList, RefreshControl } from "react-native";

const App = () => {
  const [refreshing, setRefreshing] = useState(false);
  const [data, setdata] = useState([
    { id: "1", text: "Item 1" },
    { id: "2", text: "Item 2" },
    { id: "3", text: "Item 3" },
  ]);
  function onRefresh() {
    setRefreshing(true);
    setTimeout(() => {
      setdata([{ id: "1", text: "Item 1" }]);
      setRefreshing(false);
    }, 1000);
  }
  return (
    <View>
      <FlatList
        data={data}
        renderItem={({ item }) => (
          <View>
            <Text>{item.text}</Text>
          </View>
        )}
        refreshControl={
          <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
        }
      />
    </View>
  );
};

程式講解

  1. 可以在ScrollView相關元件設定refreshControl
  2. refreshing必須提供布林值
    true開始轉圈圈
    false結束轉圈圈
  3. onRefresh則是手指下拉開始刷新時,觸發此動作
    function裡會先設定refreshing=true
    讓轉圈動畫顯示
    直到資料重新Lodaing後
    設定refreshing=false
  4. 樣式設定可參考官方,但只有顏色跟大小能改變😔

結語:
在學這兩項元件時
有點跳脫不出Html Table使用tr td去做一張資料清單

在Native不太支持使用Table形式呈現
原因是手機已經夠小了
還要將許多欄位放到小小的手機裡
造成使用者閱讀困難

在專案設計時
請跳脫往常在Web上看Table List的思維
APP在規劃時資訊清單越精簡越好
否則會「畫面很亂」

下一篇
要來介紹 React Native核心Component - Modal
在手機上也能使用彈跳視窗
對於製作子功能來講非常方便。


上一篇
Day 15 - MaterialTopTabsNavigator實作頂部切換式分頁
下一篇
Day 17 - React Native Modal實作手機彈跳視窗
系列文
單人開發者之路:React Native 與 Expo 帶你從開發到上架30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言